package com.simulador.server;
import java.util.ArrayList;
import java.util.Arrays;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;


public class Accion {
	ArrayList<String> condiciones;	//{fosforilación treonina 402, &&, (, !, ubiquitinación 123, ) }
	
	Proteina proteinaPropia; //prot a la que pertenece
	
	String sproteinaTarget; //prot que modificará
	Proteina proteinaTarget;
	String sitioTarget; //de la proteina target  (fosforilación treonina 402)
	boolean estado; //true = fosforila (en la proteina target)
	
	
	/**
	 * CONSTRUCTOR
	 * primero deben hacerse todas las proteínas y después agregarles sus acciones
	 * @param propia
	 * @param prottar
	 * @param sittar
	 * @param est
	 */
	public Accion(Proteina propia, String condicion, String prottar, String sittar, boolean est){
		condiciones = (ArrayList<String>) Arrays.asList(condicion.split(",")); //no probado
		proteinaPropia = propia;
		
		sproteinaTarget = prottar;
		proteinaTarget = ArchivoImpl.proyecto.getProt(sproteinaTarget); 
		sitioTarget = sittar;
		estado = est;
	}
	public Accion(String propia, String condicion, String prottar, String sittar, boolean est){
		this(ArchivoImpl.proyecto.getProt(propia), condicion, prottar, sittar, est);
	}
	
	//Para crear una acción
	public void addCondicion(String cond) {
		condiciones.add(cond);
	}

	//Setters
	public void setSitioTarget(String sitioTarget) {
		this.sitioTarget = sitioTarget;
	}

	public void setEstado(boolean est) {
		this.estado = est;
	}

	public void setTarget(String target) {
		this.sproteinaTarget = target;
	}
	
	/**
	 * Ejecuta la accion
	 * y llama a ejecutar las siguientes proteínas
	 * si es que se modificaron
	 * @throws ScriptException
	 */	
	public void ejecutar() throws ScriptException{
		if(verificarCondicion()){
			if(proteinaTarget.setModPos(sitioTarget, estado) != estado){ //si la modificacion cambia su estado:
				proteinaTarget.ejecutar(); //la proteina target revisa si tiene que ejecutar acciones
			}
		}else{
			//regresar al estado inicial REVISAR
			if(proteinaTarget.setModPos(sitioTarget, !estado) != !estado){ //revierte el estado REVISAR
				proteinaTarget.ejecutar(); 
			}
		}
	}

	/**
	 * Verifica la condición de la acción llamando a JavaScript para resolver la operación booleana 
	 * @return
	 * @throws ScriptException
	 */
	private boolean verificarCondicion() throws ScriptException{
		String script = "";
		for(String key : condiciones){
			if(key.contains("&&") || key.contains("||") || key.contains("(") || key.contains(")") || key.contains("!")){
				script = script + " " + key;
			}else{
				script = script + " " + proteinaPropia.getModPost(key);
			}
		}
		ScriptEngineManager mgr = new ScriptEngineManager();
	    ScriptEngine engine = mgr.getEngineByName("JavaScript");
	    return new Boolean(""+(engine.eval(script)));
	}
	
	
}







